﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Collections;
using System.Threading;
using System.IO;
using HslCommunication.Profinet.Omron;
using HslCommunication;
using FastData;
namespace FastCtr
{
    public partial class OmroPLC : UserControl
    {
        public static event Action<OmroPLC, object> OnErrOcurred;
        Mode mode = Mode.Stopping;
        public VarSave<List<string>> PlcListVarname;
        public Hashtable ContempData = new Hashtable();
        public VarSave<string> PlcIpAddress;
        public VarSave<int> PlcCircletime;
        public VarSave<string> HeartBeatAdress;
        
        public VarSave<List<ListenVar>> PlcListenArryNameList;
        public int espTimer = 0;

        public Task task = new Task(() => { });
        object obj_lock = new object();

        public Dictionary<string, Task> TaskDic = new Dictionary<string, Task>();
        Dictionary<string, Task> taskdic;

        object dialoglock = new object();

        private readonly object lock_rwData = new object();

        public OmronCipNet omron1;

        public bool State = false;
        public TimeSpan DelayTime;
        public VarSave<int> HeartBeatCircleTime;
        public VarSave<Dictionary<string, string>> DicVarDetail;
        private bool isheartbeatAdressRightConfig = false;
        private bool isplcIPRightConfig = false;
        private bool isListenVarEnoughConfig = false;
        private bool isListenVarRightConfig = false;
        public event Action<string, object> OnPlcReceivedValueChanged;
        enum Mode
        {
            Listening,
            Stopping
        }
        public OmroPLC()
        {
            InitializeComponent();
        }
        public OmroPLC(string name)
        {
            InitializeComponent();
            Name = name;
            if (!FastData.DesignHelper.IsDesignMode)
            {
                try
                {
                    DicVarDetail = new VarSave<Dictionary<string, string>>($"{Name}.DicVarDetail");
                    HeartBeatCircleTime = new VarSave<int>($"{Name}_WriteToPlcHeartBeatCircleTime");//心跳频次
                    PlcListVarname = new VarSave<List<string>>($"{Name}_PlcListVarname");
                    PlcIpAddress = new VarSave<string>($"{Name}_PlcIpAddress");
                    PlcCircletime = new VarSave<int>($"{Name}_PlcCircletime");
                    HeartBeatAdress = new VarSave<string>($"{Name}_PLCHeartBeatAdress");
                    PlcListenArryNameList = new VarSave<List<ListenVar>>($"{Name}_PlcListenArryNameList");
                    InitSetting();
                    PlcListVarname.Value.Clear();
                    PlcListVarname.Value = DicVarDetail.Value.Keys.ToList();

                }
                catch (Exception exp)
                {
                    MessageBox.Show(Name + ": PLC配置参数初始化失败！\r\n" + exp);
                }

                Task.Factory.StartNew(() =>
                {
                    StartReceivingMessage();
                }, TaskCreationOptions.LongRunning);
            }
        }

        protected virtual void InitSetting() { }

        public bool Connect()
        {
           
            omron1 = new OmronCipNet(PlcIpAddress.Value);
            OperateResult operateResult1 = omron1.ConnectServer();
            isplcIPRightConfig = operateResult1.IsSuccess;
            if (operateResult1.IsSuccess)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public bool DisConnect()
        {
            // PlcCompolet.Active = false;
            OperateResult operateResult = omron1.ConnectClose();
            if (!operateResult.IsSuccess)
            {
                return true;
            }
            else
            {
                return false;
            }
        }


        //zc20200921
        /// <summary>
        /// 读单个变量
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="varname"></param>
        /// <returns></returns>
        public T ReadVariable<T>(string varname)
        {
            lock (lock_rwData)
            {
                dynamic operateResult = new object();
                string tt = typeof(T).ToString();
                try
                {
                    switch (tt)
                    {
                        case "System.Boolean":
                            operateResult = omron1.ReadBool(varname);
                            break;
                        case "System.Single":
                            operateResult = omron1.ReadFloat(varname);
                            break;
                        case "System.Int32":
                            operateResult = omron1.ReadInt32(varname);
                            if (operateResult.Message.Contains("索引超出了数组界限"))
                            {
                                OperateResult<short> operateResult2 = omron1.ReadInt16(varname);
                                OperateResult<int> operateResult1 = new OperateResult<int>();
                                operateResult1.IsSuccess = operateResult2.IsSuccess;
                                operateResult1.Message = operateResult2.Message;
                                operateResult1.ErrorCode = operateResult2.ErrorCode;
                                operateResult1.Content = operateResult2.Content;
                                operateResult = operateResult1;
                            }
                            break;
                        case "System.Int16":
                            operateResult = omron1.ReadInt16(varname);
                            break;
                        case "System.String":
                            operateResult = omron1.ReadString(varname);
                            break;
                        case "System.Double":
                            operateResult = omron1.ReadDouble(varname);
                            break;
                    }
                }
                catch { }
                OperateResult<T> result = (OperateResult<T>)operateResult;
                if (result.IsSuccess)
                {
                    return result.Content;

                }
                else
                {
                    Thread.Sleep(500);
                    return ReadVariable<T>(varname);
                }
            }
        }

        public string ReadVariableString(string varname)
        {

            OperateResult<string> operateResult = new OperateResult<string>();
            try
            {
                operateResult = omron1.ReadString(varname);
            }
            catch { }

            if (operateResult.IsSuccess)
            {
                return operateResult.Content;
            }
            else
            {
                Thread.Sleep(500);
                return ReadVariableString(varname);
            }
        }

        private Hashtable TestMultiVariable(List<ListenVar> listenVars)
        {

            return ReadMultiVariable(listenVars);
        }


        /// <summary>
        /// 读多个数组变量
        /// </summary>
        /// <param name="varnames"></param>
        /// <returns></returns>
        /// 
        //
       // List<ListenVar> listenVars1=new List<ListenVar>() { new ListenVar("",2,BaseType.String.ToString())}
        private Hashtable ReadMultiVariable(List<ListenVar> listenVarList)
        {
            try
            {
                Hashtable hashtable = new Hashtable();
                foreach (ListenVar listenVar in listenVarList)
                {
                    string arryname = listenVar.Name;
                    ushort lenth = Convert.ToUInt16(listenVar.Length);
                    dynamic operateResults;
                    switch (listenVar.Type)
                    {
                        case "Int16":
                            operateResults = omron1.ReadInt16(arryname, lenth);
                            break;
                        case "Int32":
                            operateResults = omron1.ReadInt32(arryname, lenth);
                            break;
                        case "Int64":
                            operateResults = omron1.ReadInt64(arryname, lenth);
                            break;
                        case "Single":
                            operateResults = omron1.ReadFloat(arryname, lenth);
                            break;
                        case "Double":
                            operateResults = omron1.ReadDouble(arryname, lenth);
                            break;
                        case "String":
                            operateResults = ReadString(arryname, lenth);
                            break;
                        case "Boolean":
                            operateResults = omron1.ReadBoolArray(arryname);
                            break;
                        default:
                            operateResults = new OperateResult();
                            break;
                    }
                    if (operateResults.IsSuccess)
                    {
                        for (int i = 0; i < lenth; i++)
                        {
                            hashtable.Add($"{arryname}[{i}]", operateResults.Content[i]);
                        }
                    }
                    else
                    {
                        throw new Exception("plc read err");
                    }
                }
                return hashtable;
            }
            catch (Exception e)
            {
                OnErrOcurred?.Invoke(this, e);
                try
                {
                    Thread.Sleep(500);
                    omron1.ConnectClose();
                    omron1.Dispose();
                    omron1 = new OmronCipNet(PlcIpAddress.Value);
                    omron1.ConnectTimeOut = 1000;
                    omron1.ReceiveTimeOut = 1000;
                    OperateResult operateResult = omron1.ConnectServer();
                    isplcIPRightConfig = operateResult.IsSuccess;
                }
                catch (Exception exp)
                {

                }
                throw new Exception(e.ToString());
            }
        }


        private OperateResult<string[]> ReadString( string arryname,uint lenth)
        {
            OperateResult<string[]> operateResults = new OperateResult<string[]>();
            operateResults.Content = new string[lenth];
            operateResults.IsSuccess = true;
            operateResults.ErrorCode = 0;
            operateResults.Message = "";
            for (int i = 0; i < lenth; i++)
            {
                OperateResult<string> operate = omron1.ReadString($"{arryname}[{i}]");
                operateResults.Content[i] = operate.Content;
                operateResults.ErrorCode = operateResults.ErrorCode + operate.ErrorCode;
                operateResults.IsSuccess = operateResults.IsSuccess && operate.IsSuccess;
                operateResults.Message += operate.Message + "-";
            }
            return operateResults;

        }

        //zc20200921
        /// <summary>
        /// 写单个变量
        /// </summary>
        /// <param name="varname"></param>
        /// <param name="value"></param>
        /// 
        int wp = 0;
        public void WriteVariable(string varname, object value)
        {
            int kk = Environment.TickCount;
            OperateResult operateResult = new OperateResult();
            string tt = value.GetType().ToString();
            try
            {
                switch (tt)
                {
                    case "System.Boolean":
                        operateResult = omron1.Write(varname, Convert.ToBoolean(value));
                        break;
                    case "System.Single":
                        operateResult = omron1.Write(varname, Convert.ToSingle(value));
                        break;
                    case "System.Int32":
                    //operateResult = omron1.Write(varname, Convert.ToInt32(value));
                    //break;
                    case "System.Int16":
                        operateResult = omron1.Write(varname, Convert.ToInt16(value));
                        break;
                    case "System.String":
                        operateResult = omron1.Write(varname, Convert.ToString(value));
                        break;
                    case "System.Double":
                        operateResult = omron1.Write(varname, Convert.ToDouble(value));
                        break;
                }
            }
            catch { }
            if (operateResult.IsSuccess)
            {

            }
            else if (operateResult.Message.Contains("匹配标记"))
            {
                MessageBox.Show($"PLC变量 {varname} 不存在,请检查");
            }
            else
            {
                Thread.Sleep(500);
                WriteVariable(varname, value);
            }
            int aa = Environment.TickCount - kk;

        }

        int sign = 0;
        int circlecount = 0;
        bool heartflag = false;
        DateTime timeoutsign = DateTime.Now.Subtract(new TimeSpan(0, 0, 0, 0, 500));
        int sTimer;
        public void StartReceivingMessage()
        {

            Task taskState = new Task(() =>
            {
                while (true)
                {
                    Thread.Sleep(100);
                    DelayTime = DateTime.Now - timeoutsign;
                    if (DelayTime >= new TimeSpan(0, 0, 0, 0, 500))
                    {
                        State = false;
                    }
                    else
                    {
                        State = true;
                    }
                }
            }, TaskCreationOptions.LongRunning);
            taskState.Start();

            if (mode != Mode.Listening)
            {
                mode = Mode.Listening;
                Hashtable hashtable;
                task = new Task(() =>
                {
                    while (mode == Mode.Listening)
                    {
                        switch (sign)
                        {
                            case 0:
                                try
                                {
                                    if (omron1 != null)
                                    {
                                        omron1.ConnectClose();
                                        omron1.Dispose();
                                    }
                                    omron1 = new OmronCipNet(PlcIpAddress.Value);
                                    omron1.ConnectTimeOut = 1000;
                                    omron1.ReceiveTimeOut = 1000;
                                    OperateResult operateResult = omron1.ConnectServer();
                                    isplcIPRightConfig = operateResult.IsSuccess;
                                    if (!operateResult.IsSuccess)
                                    {
                                        throw new Exception("plcl连接失败！");
                                    }
                                    else
                                    {
                                        sign = 1;
                                    }
                                }
                                catch
                                {
                                    if (omron1 != null)
                                    {
                                        omron1.ConnectClose();
                                        omron1.Dispose();
                                    }
                                    sign = 0;
                                }

                                break;

                            case 1:
                                try
                                {

                                    OperateResult operateResult = omron1.ReadBool(HeartBeatAdress.Value);
                                    if (!operateResult.IsSuccess)
                                    {
                                        isheartbeatAdressRightConfig = false;
                                        throw new Exception("心跳信号读取异常");
                                    }
                                    else
                                    {
                                        isheartbeatAdressRightConfig = true;
                                    }
                                    sign = 2;
                                }
                                catch
                                {
                                    sign = 0;
                                }
                                break;
                            case 2:

                                if (PlcListenArryNameList.Value.Count == 0)
                                {
                                    isListenVarEnoughConfig = false;
                                    sign = 0;
                                }
                                else
                                {
                                    isListenVarEnoughConfig = true;
                                    sign = 3;
                                }
                                break;


                            case 3:
                                try
                                {
                                    //GC.Collect();
                                    hashtable = ReadMultiVariable(PlcListenArryNameList.Value);
                                    ContempData = hashtable;
                                    isListenVarRightConfig = true;
                                    sign = 4;
                                }
                                catch
                                {
                                    isListenVarRightConfig = false;
                                    sign = 0;
                                }
                                break;
                            case 4:
                                try
                                {
                                    if (PlcListenArryNameList.Value.Count == 0)
                                    {
                                        throw new Exception("至少需要添加一个监听变量");
                                    }
                                    hashtable = ReadMultiVariable(PlcListenArryNameList.Value);
                                    foreach (string name in hashtable.Keys)
                                    {
                                        if (!ContempData[name].Equals(hashtable[name]))
                                        {
                                            if (TaskDic.ContainsKey(name + "=" + hashtable[name]))
                                            {
                                                if (TaskDic[name + "=" + hashtable[name]].IsCompleted || TaskDic[name + "=" + hashtable[name]].IsCanceled || TaskDic[name + "=" + hashtable[name]].IsFaulted)
                                                {
                                                    TaskDic[name + "=" + hashtable[name]].Dispose();
                                                    TaskDic.Remove(name + "=" + hashtable[name]);
                                                    Task callbacktask = new Task(() =>
                                                    {
                                                        OnPlcReceivedValueChanged?.Invoke(name, hashtable[name]);
                                                    }, TaskCreationOptions.LongRunning);
                                                    TaskDic.Add(name + "=" + hashtable[name], callbacktask);
                                                    callbacktask.Start();
                                                }
                                                else
                                                {
                                                    OnErrOcurred?.Invoke(this, "上次任务未完成");
                                                }
                                            }
                                            else
                                            {
                                                Task callbacktask = new Task(() =>
                                                {
                                                    OnPlcReceivedValueChanged?.Invoke(name, hashtable[name]);
                                                    //TaskDic.Remove(name + "=" + hashtable[name]);
                                                }, TaskCreationOptions.LongRunning);
                                                TaskDic.Add(name + "=" + hashtable[name], callbacktask);
                                                callbacktask.Start();
                                            }
                                        }
                                    }
                                    ContempData = hashtable;
                                    espTimer = Environment.TickCount - sTimer;
                                    sTimer = Environment.TickCount;



                                    circlecount++;
                                    if (circlecount > HeartBeatCircleTime.Value)
                                    {
                                        circlecount = 0;
                                        if (!omron1.Write(HeartBeatAdress.Value, Convert.ToBoolean(heartflag)).IsSuccess)
                                        {
                                            throw new Exception("心跳信号写入异常！");
                                        }
                                        heartflag = !heartflag;
                                    }
                                    // autoResetEvent.Set();
                                    timeoutsign = DateTime.Now;//最后一次PLC更新的时间
                                }
                                catch (Exception e)
                                {
                                    sign = 0;
                                }
                                break;
                        }

                        Thread.Sleep(PlcCircletime.Value + 10); //初始值为0过小，小于10会造成卡顿
                    }
                }, TaskCreationOptions.LongRunning);
                task.Start();
            }
            else
            {
                throw new Exception("监听模式启动失败！");
            }
        }


        /// <summary>
        /// 停止
        /// </summary>
        public void StopReceivingMessage()
        {
            mode = Mode.Stopping;
            if (task.Status == TaskStatus.Running)
                Task.WaitAll(task);
        }



        private void button7_Click(object sender, EventArgs e)
        {
            try
            {
                Connect();
                label11.BackColor = Color.LimeGreen;
            }
            catch (Exception exp)
            {
                MessageBox.Show(exp.ToString());
                label11.BackColor = Color.Red;
            }
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            timer1.Enabled = false;
           // Application.DoEvents();
            if (!isplcIPRightConfig)
            {
                label17.ForeColor = Color.Red;
                label17.Text = "请检查IP配置,或者网络连接";
                label16.ForeColor = Color.Red;
                label16.Text = "待确认...";
                label18.ForeColor = Color.Red;
                label18.Text = "待确认...";
            }
            else
            {
                label17.ForeColor = Color.Green;
                label17.Text = "OK";
                if (!isheartbeatAdressRightConfig)
                {
                    label16.ForeColor = Color.Red;
                    label16.Text = "请检查心跳地址配置,且必须为BOOL类型";
                    label18.ForeColor = Color.Red;
                    label18.Text = "待确认...";
                }
                else
                {
                    label16.ForeColor = Color.Green;
                    label16.Text = "OK";
                    if (!isListenVarEnoughConfig)
                    {
                        label18.ForeColor = Color.Red;
                        label18.Text = "请配置至少一个监听数组变量";
                    }
                    else if (!isListenVarRightConfig)
                    {
                        label18.ForeColor = Color.Red;
                        label18.Text = "请配置正确的监控数组变量";
                    }
                    else
                    {
                        label18.ForeColor = Color.Green;
                        label18.Text = "OK";
                    }
                }
            }

            
           
            if (State)
            {
                //groupBox1.Enabled = false;
                //groupBox5.Enabled = false;
                button5.Enabled = false;
                label12.Text = "监听中";
                label12.BackColor = Color.LimeGreen;
                for (int i = 0; i < listView1.Items.Count; i++)
                {
                    string var = listView1.Items[i].SubItems[0].Text;
                    if (ContempData[var] != null)
                        listView1.Items[var].SubItems[1].Text = ContempData[var].ToString();
                }
            }
            else
            {
                groupBox1.Enabled = true;
                groupBox5.Enabled = true;
                button5.Enabled = true;
                label12.Text = "不监听";
                label12.BackColor = Color.Red;
            }


            try
            {
                taskdic = TaskDic;
                List<string> tasknames = taskdic.Keys.ToList();
                for (int i = 0; i < tasknames.Count; i++)
                {
                    if (!doubleBufferListView1.Items.ContainsKey(tasknames[i]))
                    {
                        doubleBufferListView1.Items.Add(tasknames[i], tasknames[i], 0);
                        doubleBufferListView1.Items[tasknames[i]].SubItems.Add("");
                    }
                    else
                    {
                        if (taskdic.ContainsKey(tasknames[i]))
                        {
                            if (taskdic[tasknames[i]].IsCompleted)
                            {
                                doubleBufferListView1.Items[tasknames[i]].SubItems[1].Text = "空闲";
                                doubleBufferListView1.Items[tasknames[i]].SubItems[1].BackColor = Color.Blue;
                            }
                            else if (taskdic[tasknames[i]].IsFaulted)
                            {
                                doubleBufferListView1.Items[tasknames[i]].SubItems[1].Text = "错误";
                                doubleBufferListView1.Items[tasknames[i]].SubItems[1].BackColor = Color.Yellow;
                            }
                            else
                            {
                                doubleBufferListView1.Items[tasknames[i]].SubItems[1].Text = "忙碌";
                                doubleBufferListView1.Items[tasknames[i]].SubItems[1].BackColor = Color.Red;
                            }
                        }
                    }
                }
            }
            catch { }
            timer1.Enabled = true;
        }




        private void OmroPLC_ParentChanged(object sender, EventArgs e)
        {
            if (!FastData.DesignHelper.IsDesignMode)
            {
                if (Parent != null)
                {
                    timer1.Start();
                    timer2.Start();
                }
                else
                {
                    timer1.Stop();
                    timer2.Stop();
                }

                if (ParentForm != null)
                {
                    ParentForm.AutoSize = true;
                    ParentForm.Text = Name;
                    ParentForm.FormClosing += new FormClosingEventHandler(ParentForm_FormClosing);
                }
            }
        }

        private void ParentForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (ParentForm != null)
            {
                ParentForm.Invoke(new Action(() =>
                {
                    ParentForm.Controls.Clear();
                }));
            }
        }

        private void OmroPLC_Load(object sender, EventArgs e)
        {
            if (!FastData.DesignHelper.IsDesignMode)
            {
                try
                {
                    foreach (ListenVar listenVar in PlcListenArryNameList.Value)
                    {
                        comboBox3.Items.Add(listenVar.Name);
                    }
                    if (comboBox3.Items.Count > 0)
                        comboBox3.SelectedIndex = 0;
                    if (comboBox1.Items.Count > 0)
                        comboBox1.SelectedIndex = 0;

                    textBox4.Text = HeartBeatAdress.Value;
                    textBox6.Text = PlcIpAddress.Value;
                    comboBox2.Items.AddRange(PlcListVarname.Value.ToArray());
                    textBox2.Text = PlcCircletime.Value.ToString();
                    textBox10.Text = HeartBeatCircleTime.Value.ToString();
                    Dictionary<string, string> keyValuePairs = new Dictionary<string, string>();
                    keyValuePairs = DicVarDetail.Value;
                    foreach (string var in PlcListVarname.Value)
                    {
                        listView1.Items.Add(var, var, 0);
                        listView1.Items[var].SubItems.Add("0");
                    }

                    foreach (string var in keyValuePairs.Keys)
                    {
                        if (listView1.Items.ContainsKey(var))
                            listView1.Items[var].SubItems.Add(keyValuePairs[var]);
                    }
                }
                catch (Exception exp)
                {
                    FastData.DesignHelper.Log(exp.ToString());
                }
            }
        }





        private void button1_Click(object sender, EventArgs e)
        {

        }

        private void button6_Click(object sender, EventArgs e)
        {
            try
            {
                Dictionary<string, string> keyValuePairs = new Dictionary<string, string>();
                for (int i = 0; i < listView1.Items.Count; i++)
                {
                    if (listView1.Items[i].SubItems.Count >= 3)
                        keyValuePairs.Add(listView1.Items[i].SubItems[0].Text, listView1.Items[i].SubItems[2].Text);
                }
                SaveStatic.SaveBinF(Name + ".dic", keyValuePairs);

            }
            catch
            {
                MessageBox.Show("保存到本地失败！");
            }
        }

        private void button4_Click(object sender, EventArgs e)
        {
            if (DisConnect())
            {
                label11.BackColor = Color.Red;
            }
            else
            {
                label11.BackColor = Color.LimeGreen;
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            try
            {
                textBox1.Text = ContempData[comboBox2.Text].ToString();
                // textBox1.Text =ReadVariable<>
            }
            catch { }
        }

        private void button9_Click(object sender, EventArgs e)
        {
            if (!string.IsNullOrEmpty(comboBox3.Text) && !string.IsNullOrEmpty(comboBox4.Text))
            {
                if (!PlcListVarname.Value.Contains($"{comboBox3.Text}[{comboBox4.Text}]"))
                {
                    List<string> list = PlcListVarname.Value;
                    list.Add($"{comboBox3.Text}[{comboBox4.Text}]");
                    PlcListVarname.Value = list;
                    comboBox2.Items.Add($"{comboBox3.Text}[{comboBox4.Text}]");
                    listView1.Items.Add($"{comboBox3.Text}[{comboBox4.Text}]", $"{comboBox3.Text}[{comboBox4.Text}]", 0);
                    listView1.Items[$"{comboBox3.Text}[{comboBox4.Text}]"].SubItems.Add("");

                }
                else
                {
                    MessageBox.Show("变量已存在！");
                }
            }

            try
            {
                Dictionary<string, string> keyValuePairs = new Dictionary<string, string>();
                for (int i = 0; i < listView1.Items.Count; i++)
                {
                    if (listView1.Items[i].SubItems.Count >= 3)
                        keyValuePairs.Add(listView1.Items[i].SubItems[0].Text, listView1.Items[i].SubItems[2].Text);
                }
                SaveStatic.SaveBinF(Name + ".dic", keyValuePairs);

            }
            catch
            {
                MessageBox.Show("保存到本地失败！");
            }

        }

        private void button10_Click(object sender, EventArgs e)
        {

            if (!string.IsNullOrEmpty(comboBox3.Text) && !string.IsNullOrEmpty(comboBox4.Text))
            {
                List<string> list = PlcListVarname.Value;
                foreach (ListViewItem listViewItem in listView1.SelectedItems)
                {
                    list.Remove(listViewItem.Text);
                    listView1.Items.Remove(listViewItem);
                }
                PlcListVarname.Value = list;
                comboBox3.Text = string.Empty;
                comboBox4.Text = string.Empty;
            }
            try
            {
                Dictionary<string, string> keyValuePairs = new Dictionary<string, string>();
                for (int i = 0; i < listView1.Items.Count; i++)
                {
                    if (listView1.Items[i].SubItems.Count >= 3)
                        keyValuePairs.Add(listView1.Items[i].SubItems[0].Text, listView1.Items[i].SubItems[2].Text);
                }
                SaveStatic.SaveBinF(Name + ".dic", keyValuePairs);

            }
            catch
            {
                MessageBox.Show("保存到本地失败！");
            }


        }

        private void button3_Click(object sender, EventArgs e)
        {
            try
            {
                string s1 = comboBox2.Text;
                object s2 = new object();
                ListenVar listenVar = PlcListenArryNameList.Value.Where(t => comboBox2.Text.Contains(t.Name)).FirstOrDefault();
                if (listenVar != null)
                {
                    switch (listenVar.Type)
                    {
                        case "String":
                            s2 = textBox5.Text;
                            break;
                        case "Single":
                            s2 = float.Parse(textBox5.Text);
                            break;
                        case "Int16":
                            s2 = Int16.Parse(textBox5.Text);
                            break;
                        case "Int32":
                            s2 = Int32.Parse(textBox5.Text);
                            break;
                        case "Int64":
                            s2 = Int64.Parse(textBox5.Text);
                            break;
                        case "Double":
                            s2 = double.Parse(textBox5.Text);
                            break;
                        case "Boolean":
                            s2 = bool.Parse(textBox5.Text);
                            break;
                    }
                }
                else
                {
                    MessageBox.Show("未被识别的变量类型");
                    return;
                }
                Task.Factory.StartNew(() =>
                {
                    WriteVariable(s1, s2);
                }, TaskCreationOptions.LongRunning);
            }
            catch { }
        }

        private void button5_Click(object sender, EventArgs e)
        {
            try
            {
                StartReceivingMessage();
            }
            catch (Exception exp)
            {
                MessageBox.Show("监听失败！" + exp);
            }
        }


        protected override void OnHandleCreated(EventArgs e)
        {
            base.OnHandleCreated(e);
            //MessageBox.Show(Name);
            BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
        }

        private void button8_Click(object sender, EventArgs e)
        {
            StopReceivingMessage();
        }



        public void ListViewBindDataTable(ListView listview, DataTable dt)
        {
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                ListViewItem item = new ListViewItem(dt.Rows[i][0].ToString());
                for (int j = 0; j < dt.Columns.Count; j++)
                {
                    item.SubItems.Add(dt.Rows[i][j].ToString());
                }
                listview.Items.Add(item);
            }
        }



        private void listValueShow()
        {

        }

        int PlcListenArryNameListCount = 0;
        private void timer2_Tick(object sender, EventArgs e)
        {
            try
            {
                label10.Text = espTimer.ToString() + " 毫秒";
                if (PlcListenArryNameList.Value.Count != PlcListenArryNameListCount)
                {
                    PlcListenArryNameListCount = PlcListenArryNameList.Value.Count;
                    doubleBufferListView2.Items.Clear();
                    for (int i = 0; i < PlcListenArryNameList.Value.Count; i++)
                    {
                        doubleBufferListView2.Items.Add(PlcListenArryNameList.Value[i].Name, PlcListenArryNameList.Value[i].Name, 0);
                        doubleBufferListView2.Items[PlcListenArryNameList.Value[i].Name].SubItems.Add(PlcListenArryNameList.Value[i].Length.ToString());
                        doubleBufferListView2.Items[PlcListenArryNameList.Value[i].Name].SubItems.Add(PlcListenArryNameList.Value[i].Type);
                    }
                }
            }
            catch { }
        }

        private void listView1_SelectedIndexChanged(object sender, EventArgs e)
        {
            //if (listView1.SelectedItems != null)
            //    textBox3.Text = listView1.SelectedItems[0].Text;
        }

        private void listView1_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
        {
            comboBox3.Text = e.Item.SubItems[0].Text.Split('[')[0];
            comboBox4.Text = e.Item.SubItems[0].Text.Split('[')[1].Split(']')[0];
            comboBox2.Text = e.Item.SubItems[0].Text;
            if (e.Item.SubItems.Count >= 3)
                textBox8.Text = e.Item.SubItems[2].Text;
            else
                textBox8.Text = "";
        }

        private void comboBox2_DropDown(object sender, EventArgs e)
        {
            comboBox2.Items.Clear();
            comboBox2.Items.AddRange(PlcListVarname.Value.ToArray());
        }

        private void button11_Click(object sender, EventArgs e)
        {
            try
            {
                TestMultiVariable(PlcListenArryNameList.Value);
                MessageBox.Show("测试OK！");
            }
            catch
            {
                MessageBox.Show("测试失败！");
            }
        }

        private void button12_Click(object sender, EventArgs e)
        {
            if (!PlcListVarname.Value.Contains($"{comboBox3.Text}[{comboBox4.Text}]"))
            {
                MessageBox.Show("不存在变量名：" + comboBox3.Text);
                return;
            }
            if (listView1.Items[$"{comboBox3.Text}[{comboBox4.Text}]"].SubItems.Count == 2)
            {
                listView1.Items[$"{comboBox3.Text}[{comboBox4.Text}]"].SubItems.Add(textBox8.Text);
            }
            else if (listView1.Items[$"{comboBox3.Text}[{comboBox4.Text}]"].SubItems.Count == 3)
            {
                listView1.Items[$"{comboBox3.Text}[{comboBox4.Text}]"].SubItems[2].Text = textBox8.Text;
            }
            try
            {
                Dictionary<string, string> keyValuePairs = new Dictionary<string, string>();
                for (int i = 0; i < listView1.Items.Count; i++)
                {
                    if (listView1.Items[i].SubItems.Count >= 3)
                        keyValuePairs.Add(listView1.Items[i].SubItems[0].Text, listView1.Items[i].SubItems[2].Text);
                }
                SaveStatic.SaveBinF(Name + ".dic", keyValuePairs);

            }
            catch
            {
                MessageBox.Show("保存到本地失败！");
            }
        }

        private void textBox6_Validated(object sender, EventArgs e)
        {
            if (PlcIpAddress != null)
                PlcIpAddress.Value = textBox6.Text;
        }

        private void textBox4_Validated(object sender, EventArgs e)
        {
            if (HeartBeatAdress != null)
                HeartBeatAdress.Value = textBox4.Text;
        }

        private void button13_Click(object sender, EventArgs e)
        {
            if (textBox7.Text == "" || comboBox1.Text == "" || numericUpDown1.Value == 0)
            {
                MessageBox.Show("输入信息不正确！");
                return;
            }


            if (PlcListenArryNameList.Value.Where(t => t.Name == textBox7.Text).FirstOrDefault() != null)
            {
                MessageBox.Show($"数组变量{textBox7.Text}已经存在！");
                return;
            }

            List<ListenVar> listenVars = PlcListenArryNameList.Value;
            ListenVar listenVar = new ListenVar(textBox7.Text, (uint)numericUpDown1.Value, (BaseType)Enum.Parse(typeof(BaseType), comboBox1.Text));
            listenVars.Add(listenVar);
            PlcListenArryNameList.Value = listenVars;
        }



        private void doubleBufferListView2_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
        {
            try
            {
                textBox7.Text = e.Item.SubItems[0].Text;
                numericUpDown1.Value = decimal.Parse(e.Item.SubItems[1].Text);
                comboBox1.SelectedItem = e.Item.SubItems[2].Text;
            }
            catch { }


        }

        private void button14_Click(object sender, EventArgs e)
        {
            List<ListenVar> listenVars = PlcListenArryNameList.Value;
            ListenVar listenVa = listenVars.Where(t => (t.Name == textBox7.Text)).FirstOrDefault();
            listenVars.Remove(listenVa);
            PlcListenArryNameList.Value = listenVars;
        }

        private void textBox10_Validated(object sender, EventArgs e)
        {
            try
            {
                HeartBeatCircleTime.Value = int.Parse(textBox10.Text);
            }
            catch
            {

            }
        }

        private void comboBox4_Click(object sender, EventArgs e)
        {

        }

        private void comboBox4_DropDown(object sender, EventArgs e)
        {
            comboBox4.Items.Clear();
            ListenVar listenVar = PlcListenArryNameList.Value.Where(t => t.Name == comboBox3.Text).FirstOrDefault();
            if (listenVar != null)
            {
                for (int k = 0; k < listenVar.Length; k++)
                {
                    comboBox4.Items.Add(k);
                }
            }
        }

        private void comboBox3_DropDown(object sender, EventArgs e)
        {
            comboBox3.Items.Clear();
            foreach (ListenVar listenVar in PlcListenArryNameList.Value)
            {
                comboBox3.Items.Add(listenVar.Name);
            }
        }

        private void textBox2_Validated(object sender, EventArgs e)
        {
            try
            {
                PlcCircletime.Value = int.Parse(textBox2.Text);
            }
            catch
            {
                MessageBox.Show("输入信息有误！");
            }
        }

        private void label12_Click(object sender, EventArgs e)
        {

        }
    }

    [Serializable]
    public class ListenVar
    {
        public ListenVar(string name,uint length,BaseType type)
        {
            Name = name;
            Length = length;
            Type = type.ToString();
        }
        public string Name;
        public uint Length;
        public string Type;

    }

    public class DoubleBufferListView : ListView
    {
        public DoubleBufferListView()
        {
            SetStyle(ControlStyles.DoubleBuffer | ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
            UpdateStyles();
        }
    }

}
